//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using DotNetNuke.Common;
using DotNetNuke.UI.Utilities.Animation;
using DotNetNuke.UI.WebControls;
namespace DotNetNuke.NavigationControl
{
	public class DNNMenuNavigationProvider : DotNetNuke.Modules.NavigationProvider.NavigationProvider
	{
		private DNNMenu m_objMenu;
		private string m_strControlID;
		private string m_strCSSBreak;
		private string m_strCSSBreadCrumbSub;
		private string m_strCSSBreadCrumbRoot;
		private string m_strNodeSelectedSub;
		private string m_strNodeSelectedRoot;
		private string m_strCSSNodeRoot;
		private string m_strCSSNodeHoverSub;
		private string m_strCSSNodeHoverRoot;
		private string m_strNodeLeftHTMLSub = "";
		private string m_strNodeLeftHTMLBreadCrumbSub = "";
		private string m_strNodeLeftHTMLBreadCrumbRoot = "";
		private string m_strNodeLeftHTMLRoot = "";
		private string m_strNodeRightHTMLSub = "";
		private string m_strNodeRightHTMLBreadCrumbSub = "";
		private string m_strNodeRightHTMLBreadCrumbRoot = "";
		private string m_strNodeRightHTMLRoot = "";
		private string m_strSeparatorHTML = "";
		private string m_strSeparatorLeftHTML = "";
		private string m_strSeparatorLeftHTMLBreadCrumb = "";
		private string m_strSeparatorLeftHTMLActive = "";
		private string m_strSeparatorRightHTML = "";
		private string m_strSeparatorRightHTMLBreadCrumb = "";
		private string m_strSeparatorRightHTMLActive = "";
		private bool m_blnIndicateChildren;
		private string m_strPathImage;
		private System.Collections.Generic.List<UI.Skins.CustomAttribute> m_objCustomAttributes = new System.Collections.Generic.List<UI.Skins.CustomAttribute>();
		public DNNMenu Menu {
			get { return m_objMenu; }
		}
		public override System.Collections.Generic.List<UI.Skins.CustomAttribute> CustomAttributes {
			get { return m_objCustomAttributes; }
			set { m_objCustomAttributes = value; }
		}
		public override System.Web.UI.Control NavigationControl {
			get { return Menu; }
		}
		public override bool SupportsPopulateOnDemand {
			get { return true; }
		}
		public override string WorkImage {
			get { return Menu.WorkImage; }
			set { Menu.WorkImage= value; }
		}
		public override string IndicateChildImageSub {
			get { return Menu.ChildArrowImage; }
			set { Menu.ChildArrowImage= value; }
		}
		public override string IndicateChildImageRoot {
			get { return Menu.RootArrowImage; }
			set { Menu.RootArrowImage= value; }
		}
		public override string ControlID {
			get { return m_strControlID; }
			set { m_strControlID= value; }
		}
		public override Modules.NavigationProvider.NavigationProvider.Orientation ControlOrientation {
			get {
				if(Menu.Orientation == DotNetNuke.UI.WebControls.Orientation.Horizontal)
				    return Modules.NavigationProvider.NavigationProvider.Orientation.Horizontal;
				else
				    return Modules.NavigationProvider.NavigationProvider.Orientation.Vertical;
			}
			set {
				switch (value) {
					case Modules.NavigationProvider.NavigationProvider.Orientation.Horizontal:
						Menu.Orientation = DotNetNuke.UI.WebControls.Orientation.Horizontal;
						break;
					case Modules.NavigationProvider.NavigationProvider.Orientation.Vertical:
						Menu.Orientation = DotNetNuke.UI.WebControls.Orientation.Vertical;
						break;
				}
			}
		}
		public override string CSSIndicateChildSub {
			get { return ""; }
			set { }
		}
		public override string CSSIndicateChildRoot {
			get { return ""; }
			set { }
		}
		public override string CSSBreadCrumbSub {
			get { return m_strCSSBreadCrumbSub; }
			set { m_strCSSBreadCrumbSub= value; }
		}
		public override string CSSBreadCrumbRoot {
			get { return m_strCSSBreadCrumbRoot; }
			set { m_strCSSBreadCrumbRoot= value; }
		}
		public override string CSSBreak {
			get { return m_strCSSBreak; }
			set { m_strCSSBreak= value; }
		}
		public override string CSSControl {
			get { return Menu.MenuBarCssClass; }
			set { Menu.MenuBarCssClass= value; }
		}
		public override string CSSIcon {
			get { return Menu.DefaultIconCssClass; }
			set { Menu.DefaultIconCssClass= value; }
		}
		public override string CSSNode {
			get { return Menu.DefaultNodeCssClass; }
			set { Menu.DefaultNodeCssClass= value; }
		}
		public override string CSSNodeSelectedSub {
			get { return m_strNodeSelectedSub; }
			set { m_strNodeSelectedSub= value; }
		}
		public override string CSSNodeSelectedRoot {
			get { return m_strNodeSelectedRoot; }
			set { m_strNodeSelectedRoot= value; }
		}
		public override string CSSNodeHover {
			get { return Menu.DefaultNodeCssClassOver; }
			set { Menu.DefaultNodeCssClassOver= value; }
		}
		public override string CSSNodeRoot {
			get { return m_strCSSNodeRoot; }
			set { m_strCSSNodeRoot= value; }
		}
		public override string CSSNodeHoverSub {
			get { return m_strCSSNodeHoverSub; }
			set { m_strCSSNodeHoverSub= value; }
		}
		public override string CSSNodeHoverRoot {
			get { return m_strCSSNodeHoverRoot; }
			set { m_strCSSNodeHoverRoot= value; }
		}
		public override string CSSContainerSub {
			get { return Menu.MenuCssClass; }
			set { Menu.MenuCssClass= value; }
		}
		public override string ForceDownLevel {
			get { return Menu.ForceDownLevel.ToString(); }
			set { Menu.ForceDownLevel = Convert.ToBoolean(value); }
		}
		public override bool IndicateChildren {
			get { return m_blnIndicateChildren; }
			set { m_blnIndicateChildren= value; }
		}
		public override bool PopulateNodesFromClient {
			get { return Menu.PopulateNodesFromClient; }
			set { Menu.PopulateNodesFromClient= value; }
		}
		public override string NodeLeftHTMLSub {
			get { return m_strNodeLeftHTMLSub; }
			set { m_strNodeLeftHTMLSub= value; }
		}
		public override string NodeLeftHTMLBreadCrumbSub {
			get { return m_strNodeLeftHTMLBreadCrumbSub; }
			set { m_strNodeLeftHTMLBreadCrumbSub= value; }
		}
		public override string NodeLeftHTMLBreadCrumbRoot {
			get { return m_strNodeLeftHTMLBreadCrumbRoot; }
			set { m_strNodeLeftHTMLBreadCrumbRoot= value; }
		}
		public override string NodeLeftHTMLRoot {
			get { return m_strNodeLeftHTMLRoot; }
			set { m_strNodeLeftHTMLRoot= value; }
		}
		public override string NodeRightHTMLSub {
			get { return m_strNodeRightHTMLSub; }
			set { m_strNodeRightHTMLSub= value; }
		}
		public override string NodeRightHTMLBreadCrumbSub {
			get { return m_strNodeRightHTMLBreadCrumbSub; }
			set { m_strNodeRightHTMLBreadCrumbSub= value; }
		}
		public override string NodeRightHTMLBreadCrumbRoot {
			get { return m_strNodeRightHTMLBreadCrumbRoot; }
			set { m_strNodeRightHTMLBreadCrumbRoot= value; }
		}
		public override string NodeRightHTMLRoot {
			get { return m_strNodeRightHTMLRoot; }
			set { m_strNodeRightHTMLRoot= value; }
		}
		public override string SeparatorHTML {
			get { return m_strSeparatorHTML; }
			set { m_strSeparatorHTML= value; }
		}
		public override string SeparatorLeftHTML {
			get { return m_strSeparatorLeftHTML; }
			set { m_strSeparatorLeftHTML= value; }
		}
		public override string SeparatorLeftHTMLActive {
			get { return m_strSeparatorLeftHTMLActive; }
			set { m_strSeparatorLeftHTMLActive= value; }
		}
		public override string SeparatorLeftHTMLBreadCrumb {
			get { return m_strSeparatorLeftHTMLBreadCrumb; }
			set { m_strSeparatorLeftHTMLBreadCrumb= value; }
		}
		public override string SeparatorRightHTML {
			get { return m_strSeparatorRightHTML; }
			set { m_strSeparatorRightHTML= value; }
		}
		public override string SeparatorRightHTMLActive {
			get { return m_strSeparatorRightHTMLActive; }
			set { m_strSeparatorRightHTMLActive= value; }
		}
		public override string SeparatorRightHTMLBreadCrumb {
			get { return m_strSeparatorRightHTMLBreadCrumb; }
			set { m_strSeparatorRightHTMLBreadCrumb= value; }
		}
		public override string PathSystemImage {
			get { return Menu.SystemImagesPath; }
			set { Menu.SystemImagesPath= value; }
		}
		public override string PathImage {
			get { return m_strPathImage; }
			set { m_strPathImage= value; }
		}
		public override string PathSystemScript {
			get { return Menu.MenuScriptPath; }
			set { }
		}
		public override void Initialize()
		{
			m_objMenu = new DNNMenu();
			Menu.ID = m_strControlID;
			Menu.EnableViewState = false;
			Menu.NodeClick += DNNMenu_NodeClick;
			Menu.PopulateOnDemand += DNNMenu_PopulateOnDemand;
		}
		public override void Bind(DotNetNuke.UI.WebControls.DNNNodeCollection objNodes)
		{
			DotNetNuke.UI.WebControls.DNNNode objNode = null;
			MenuNode objMenuItem;
			DotNetNuke.UI.WebControls.DNNNode objPrevNode = null;
			bool RootFlag = false;
			int intIndex;
			if (IndicateChildren == false) {
				IndicateChildImageSub = "";
				IndicateChildImageRoot = "";
			}
			if (!String.IsNullOrEmpty(this.CSSNodeSelectedRoot) && this.CSSNodeSelectedRoot == this.CSSNodeSelectedSub) {
				Menu.DefaultNodeCssClassSelected = this.CSSNodeSelectedRoot;
			}
			foreach (DotNetNuke.UI.Skins.CustomAttribute objAttr in this.CustomAttributes) {
				switch (objAttr.Name.ToLower()) {
					case "submenuorientation":
						this.Menu.SubMenuOrientation = (DotNetNuke.UI.WebControls.Orientation)System.Enum.Parse(this.Menu.SubMenuOrientation.GetType(), objAttr.Value);
						break;
					case "usetables":
						this.Menu.RenderMode = DNNMenu.MenuRenderMode.Normal;
						break;
					case "rendermode":
						this.Menu.RenderMode = (DNNMenu.MenuRenderMode)System.Enum.Parse(typeof(DNNMenu.MenuRenderMode), objAttr.Value);
						break;
					case "animationtype":
						this.Menu.Animation.AnimationType = (AnimationType)System.Enum.Parse(typeof(AnimationType), objAttr.Value);
						break;
					case "easingdirection":
						this.Menu.Animation.EasingDirection = (EasingDirection)System.Enum.Parse(typeof(EasingDirection), objAttr.Value);
						break;
					case "easingtype":
						this.Menu.Animation.EasingType = (EasingType)System.Enum.Parse(typeof(EasingType), objAttr.Value);
						break;
					case "animationinterval":
						this.Menu.Animation.Interval = int.Parse(objAttr.Value);
						break;
					case "animationlength":
						this.Menu.Animation.Length = int.Parse(objAttr.Value);
						break;
				}
			}
			foreach (DotNetNuke.UI.WebControls.DNNNode node in objNodes)
			{
				objNode = node;
				if (objNode.Level == 0) {
					intIndex = Menu.MenuNodes.Import(objNode, false);
					objMenuItem = Menu.MenuNodes[intIndex];
					if (objNode.BreadCrumb && string.IsNullOrEmpty(NodeRightHTMLBreadCrumbRoot) == false) {
						objMenuItem.RightHTML += NodeRightHTMLBreadCrumbRoot;
					} else if (string.IsNullOrEmpty(this.NodeRightHTMLRoot) == false) {
						objMenuItem.RightHTML = NodeRightHTMLRoot;
					}
					if (RootFlag == true) {
						AddSeparator("All", objPrevNode, objNode, objMenuItem);
					} else {
						if (string.IsNullOrEmpty(SeparatorLeftHTML) == false || string.IsNullOrEmpty(SeparatorLeftHTMLBreadCrumb) == false || string.IsNullOrEmpty(this.SeparatorLeftHTMLActive) == false) {
							AddSeparator("Left", objPrevNode, objNode, objMenuItem);
						}
						RootFlag = true;
					}
					if (objNode.BreadCrumb && string.IsNullOrEmpty(NodeLeftHTMLBreadCrumbRoot) == false) {
						objMenuItem.LeftHTML += NodeLeftHTMLBreadCrumbRoot;
					} else if (string.IsNullOrEmpty(this.NodeLeftHTMLRoot) == false) {
						objMenuItem.LeftHTML += this.NodeLeftHTMLRoot;
					}
					if (!String.IsNullOrEmpty(this.CSSNodeRoot)) {
						objMenuItem.CSSClass = this.CSSNodeRoot;
					}
					if (!String.IsNullOrEmpty(this.CSSNodeHoverRoot) && this.CSSNodeHoverRoot != this.CSSNodeHoverSub) {
						objMenuItem.CSSClassHover = this.CSSNodeHoverRoot;
					}
					objMenuItem.CSSIcon = " ";
					if (objNode.BreadCrumb) {
						if (!String.IsNullOrEmpty(CSSBreadCrumbRoot))
							objMenuItem.CSSClass = CSSBreadCrumbRoot;
						if (objNode.Selected && String.IsNullOrEmpty(Menu.DefaultNodeCssClassSelected)) {
							objMenuItem.CSSClassSelected = this.CSSNodeSelectedRoot;
						}
					}
				} else {
					try {
						MenuNode objParent = Menu.MenuNodes.FindNode(objNode.ParentNode.ID);
						if (objParent == null) {
							objParent = Menu.MenuNodes[Menu.MenuNodes.Import(objNode.ParentNode.Clone(), true)];
						}
						objMenuItem = objParent.MenuNodes.FindNode(objNode.ID);
						if (objMenuItem == null) {
							objMenuItem = objParent.MenuNodes[objParent.MenuNodes.Import(objNode.Clone(), true)];
						}
						if (!String.IsNullOrEmpty(NodeLeftHTMLSub))
							objMenuItem.LeftHTML = NodeLeftHTMLSub;
						if (!String.IsNullOrEmpty(NodeRightHTMLSub))
							objMenuItem.RightHTML = this.NodeRightHTMLSub;
						if (!String.IsNullOrEmpty(CSSNodeHoverSub) && this.CSSNodeHoverRoot != this.CSSNodeHoverSub) {
							objMenuItem.CSSClassHover = CSSNodeHoverSub;
						}
						if (objNode.BreadCrumb) {
							if (!String.IsNullOrEmpty(CSSBreadCrumbSub))
								objMenuItem.CSSClass = this.CSSBreadCrumbSub;
							if (!String.IsNullOrEmpty(NodeLeftHTMLBreadCrumbSub))
								objMenuItem.LeftHTML = NodeLeftHTMLBreadCrumbSub;
							if (!String.IsNullOrEmpty(NodeRightHTMLBreadCrumbSub))
								objMenuItem.RightHTML = NodeRightHTMLBreadCrumbSub;
							if (objNode.Selected && String.IsNullOrEmpty(Menu.DefaultNodeCssClassSelected)) {
								objMenuItem.CSSClass = this.CSSNodeSelectedSub;
							}
						}
					} catch {
						objMenuItem = null;
					}
				}
				if (!String.IsNullOrEmpty(objNode.Image)) {
					if (objNode.Image.StartsWith("~/images/")) {
						objNode.Image = objNode.Image.Replace("~/images/", this.PathSystemImage);
					} else if (objNode.Image.StartsWith("~/")) {
						objNode.Image = Globals.ResolveUrl(objNode.Image);
					} else if (objNode.Image.StartsWith("/") == false && !String.IsNullOrEmpty(this.PathImage)) {
						objNode.Image = this.PathImage + objNode.Image;
					}
					objMenuItem.Image = objNode.Image;
				}
				if (objMenuItem.IsBreak) {
					objMenuItem.CSSClass = this.CSSBreak;
				}
				objMenuItem.ToolTip = objNode.ToolTip;
				Bind(objNode.DNNNodes);
				objPrevNode = objNode;
			}
			if (objNode != null && objNode.Level == 0) {
				if (!String.IsNullOrEmpty(IndicateChildImageSub) && IndicateChildImageSub.IndexOf("/") == -1)
					IndicateChildImageSub = this.PathSystemImage + IndicateChildImageSub;
				if (!String.IsNullOrEmpty(IndicateChildImageRoot) && IndicateChildImageRoot.IndexOf("/") == -1)
					IndicateChildImageRoot = this.PathSystemImage + IndicateChildImageRoot;
			}
		}
		private void AddSeparator(string strType, DotNetNuke.UI.WebControls.DNNNode objPrevNode, DotNetNuke.UI.WebControls.DNNNode objNextNode, MenuNode objMenuItem)
		{
			string strLeftHTML = SeparatorLeftHTML + SeparatorLeftHTMLBreadCrumb + SeparatorLeftHTMLActive;
			string strRightHTML = SeparatorRightHTML + SeparatorRightHTMLBreadCrumb + SeparatorRightHTMLActive;
			string strHTML = this.SeparatorHTML + strLeftHTML + strRightHTML;
			if (!String.IsNullOrEmpty(strHTML)) {
				string strSeparator = "";
				string strSeparatorLeftHTML = "";
				string strSeparatorRightHTML = "";
				string strSeparatorClass = "";
				string strLeftSeparatorClass = "";
				string strRightSeparatorClass = "";
				if (string.IsNullOrEmpty(strLeftHTML) == false) {
					strLeftSeparatorClass = this.GetSeparatorText(CSSLeftSeparator, CSSLeftSeparatorBreadCrumb, CSSLeftSeparatorSelection, objNextNode);
					strSeparatorLeftHTML = this.GetSeparatorText(SeparatorLeftHTML, SeparatorLeftHTMLBreadCrumb, SeparatorLeftHTMLActive, objNextNode);
				}
				if (string.IsNullOrEmpty(SeparatorHTML) == false) {
					if (!String.IsNullOrEmpty(CSSSeparator))
						strSeparatorClass = CSSSeparator;
					strSeparator = SeparatorHTML;
				}
				if (string.IsNullOrEmpty(strRightHTML) == false) {
					strRightSeparatorClass = this.GetSeparatorText(CSSRightSeparator, CSSRightSeparatorBreadCrumb, CSSRightSeparatorSelection, objNextNode);
					strSeparatorRightHTML = this.GetSeparatorText(SeparatorRightHTML, SeparatorRightHTMLBreadCrumb, SeparatorRightHTMLActive, objNextNode);
				}
				if (string.IsNullOrEmpty(strSeparatorRightHTML) == false) {
					objMenuItem.RightHTML += GetSeparatorMarkup(strRightSeparatorClass, strSeparatorRightHTML);
				}
				if (string.IsNullOrEmpty(strSeparator) == false && strType == "All") {
					objMenuItem.LeftHTML += GetSeparatorMarkup(strSeparatorClass, strSeparator);
				}
				if (string.IsNullOrEmpty(strSeparatorLeftHTML) == false) {
					objMenuItem.LeftHTML += GetSeparatorMarkup(strLeftSeparatorClass, strSeparatorLeftHTML);
				}
			}
		}
		private string GetSeparatorText(string strNormal, string strBreadCrumb, string strSelection, DotNetNuke.UI.WebControls.DNNNode objNode)
		{
			string strRet = "";
			if (!String.IsNullOrEmpty(strNormal)) {
				strRet = strNormal;
			}
			if (!String.IsNullOrEmpty(strBreadCrumb) && objNode != null && objNode.BreadCrumb) {
				strRet = strBreadCrumb;
			}
			if (!String.IsNullOrEmpty(strSelection) && objNode != null && objNode.Selected) {
				strRet = strSelection;
			}
			return strRet;
		}
		private string GetSeparatorMarkup(string strClass, string strHTML)
		{
			string strRet = "";
			if (string.IsNullOrEmpty(strClass) == false) {
				strRet += "<span class=\"" + strClass + "\">" + strHTML + "</span>";
			} else {
				strRet += strHTML;
			}
			return strRet;
		}
		private void DNNMenu_NodeClick(object source, UI.WebControls.DNNMenuNodeClickEventArgs e)
		{
			base.RaiseEvent_NodeClick(e.Node);
		}
		private void DNNMenu_PopulateOnDemand(object source, UI.WebControls.DNNMenuEventArgs e)
		{
			base.RaiseEvent_PopulateOnDemand(e.Node);
		}
		public override void ClearNodes()
		{
			Menu.MenuNodes.Clear();
		}
	}
}
